% I want to be able to do the following operations to work with HID usage
% pages and usages, names and numbers:
%   - page name -> page number
%   - page number -> page name
%   - usage name -> usage number, given page number
%   - usage number -> usage name, given page number
%
% What I need is a clean-formatted file with the usage info.  It seems, for
% some reason, USB.org only to supplies an annotated .pdf!  How are people
% supposed to work with this programmatically?  Where's the XML??
%
% I found two other options:
%   - usb_hid_usages.txt from www.freebsd.org.  Nice plaintext but
%   mysterious origin.  Update process?
%   - IOHIDUsageTables.h, from the OS X UIKit framework.  Easily scrapeable
%   enums with consistent prefixes.  Maybe a bit klugdy to match usages
%   with pages, but certainly doable.  Same update process as mexHID
%   itself.
% Both are probably fine.  I'm going with IOHIDUsageTables.h because I'm
% already using UIKit.

% The Map builder should take a path to IOHIDUsageTables.h:
usageHeaderPath = '/System/Library/Frameworks/IOKit.framework/Versions/A/Headers/hid/IOHIDUsageTables.h';

% I should include the builder with Snow Dots.  I should also save the Maps
% in a .mat file, include that, and use it by default.

% This should pick a page out of the header enum.  The tokens are
%   - the page name
%   - the page number in hex
pageEnum = 'kHIDPage_(\w+)\W=\W0x(\w+)';

% This should locate the usage enum for a usage page.  The token is
%   - the page number in hex
pageUsageEnumFinder = 'Page\W\(0x(\w+)\)\W\*\/';

% This should pick a usage out of an enum.  The tokens are
%   - Apple's abbreviated usage page name
%   - the usage name
%   - the usage number in hex
usageEnum = 'kHIDUsage_(\w+_)(\w+)\W=\W0x(\w+)';

% I'll convert hex numbers to decimal since this is what users understand
% and what works with the mexHID property matching

% I want to build:
%   pageNumberToName Map
%   pageNameToNumber Map
%   usageNumberToName Maps Map, keyed by page number
%   usageNameToNumber Maps Map, keyed by page number

% I can build these by scanning IOHIDUsageTables line by line:
%   match pageEnum?
%       - new entry each in pageNumberToName and pageNameToNumber
%       - new Map each inserted into usageNumberToName and usageNameToNumber
%   match pageUsageEnumFinder?
%       - set the current page number
%   match usageEnum?
%       - new entry each into usageNumberToName and usageNameToNumber, for
%       the current page number

% I can save these as regular variables to a mat file and load them into
% properties of some class on first use.  A singleton class, I guess, with
% a bunch of static methods for the 4 ops above.

% Maybe the class should be a dotsAllSingletons subclass.  That would imply
% a gui, which is consistent with the Snow Dots philosophy.  It would also
% imply that lookups are implemented as topsGroupedList instead of just
% Map.  What would the lists look like?  How about the ops are still
% implemented cleanly as Maps, but there's also a topsGroupedList for
% gui/summary.  It could have:
%   page name groups, each with
%       a page name mnemonic and page number item
%       usage name mnemonics and usage number items
% Perhaps there's also a reverse list with:
%   page number groups, each with
%       a -1 mnemonic and page name item
%       usage number mnemonics and usage name items

% On second thought, let mexHIDUsage be independent of Snow Dots or Tower
% of Psych.  Just stick to containers.Maps

% The mexHIDUsage class interface could be:
% Properties:
%   pageNumberToName Map
%   pageNameToNumber Map
%   usageNumberToName Maps Map, keyed by page number
%   usageNameToNumber Maps Map, keyed by page number
%   mexHIDUsageMat path to .mat file wit Maps
%
% Instance:
%   initialize - loads mexHIDUsagesPath and loads Maps into properties
%   buildUsageTables(headerPath) - scans IOHIDUsageTables.h, overwrites
%   mexHIDUsageMat, reinitializes.  Should need only once.
%
% Static:
%   theObject
%   reset
%   gui - launches guis?
%   nameForPageNumber(pageNumber) - looks up page name
%   numberForPageName(pageName) - looks up page number
%   numberForUsageNameOnPage(pageName, pageNumber) - looks up usage number
%   nameForUsageNumberOnPage(pageNumber, pageNumber) - looks up usage name